package com.zxy.ziems.server.device.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zxy.btp.common.response.PageResult;
import com.zxy.ziems.server.alarm.enums.AlarmTypeParamEnum;
import com.zxy.ziems.server.alarm.pojo.vo.AlarmRecordDeviceVO;
import com.zxy.ziems.server.alarm.service.AlarmRecordService;
import com.zxy.ziems.server.classify.service.ClassifyDevicePropertyService;
import com.zxy.ziems.server.collection.pojo.entity.DlPointEntity;
import com.zxy.ziems.server.collection.service.DlPointService;
import com.zxy.ziems.server.device.controller.DeviceTreeVO;
import com.zxy.ziems.server.device.convertor.DeviceConvertor;
import com.zxy.ziems.server.device.mapper.DeviceMapper;
import com.zxy.ziems.server.device.pojo.bo.Coordinate;
import com.zxy.ziems.server.device.pojo.dto.BatchAddDevicePropertyDTO;
import com.zxy.ziems.server.device.pojo.dto.DeviceBaseDTO;
import com.zxy.ziems.server.device.pojo.dto.DeviceDTO;
import com.zxy.ziems.server.device.pojo.dto.DevicePropertyDTO;
import com.zxy.ziems.server.device.pojo.entity.ChannelDeviceEntity;
import com.zxy.ziems.server.device.pojo.entity.ChannelEntity;
import com.zxy.ziems.server.device.pojo.entity.DeviceEntity;
import com.zxy.ziems.server.device.pojo.entity.DeviceTypeEntity;
import com.zxy.ziems.server.device.pojo.param.DeviceQueryParam;
import com.zxy.ziems.server.device.pojo.vo.DeviceAlarmVO;
import com.zxy.ziems.server.device.pojo.vo.DeviceVO;
import com.zxy.ziems.server.device.pojo.vo.SceneDeviceAlarmCountVO;
import com.zxy.ziems.server.device.service.*;
import com.zxy.ziems.server.domain.Org;
import com.zxy.ziems.server.file.entity.FileEntity;
import com.zxy.ziems.server.file.service.FileService;
import com.zxy.ziems.server.monitor.service.MonitorGroupDeviceService;
import com.zxy.ziems.server.mybatis.core.query.LambdaQueryWrapperX;
import com.zxy.ziems.server.mybatis.core.query.QueryWrapperX;
import com.zxy.ziems.server.mybatis.core.query.WrapperX;
import com.zxy.ziems.server.mybatis.core.service.ServiceImplX;
import com.zxy.ziems.server.scene.convertor.SceneConvertor;
import com.zxy.ziems.server.scene.pojo.entity.SceneEntity;
import com.zxy.ziems.server.scene.pojo.enums.SceneType;
import com.zxy.ziems.server.scene.pojo.param.SceneTreeParam;
import com.zxy.ziems.server.scene.pojo.vo.SceneTreeAlarmVO;
import com.zxy.ziems.server.scene.service.SceneService;
import com.zxy.ziems.server.service.OrgService;
import com.zxy.ziems.server.utils.AssertUtil;
import com.zxy.ziems.server.utils.BusinessExceptionUtil;
import com.zxy.ziems.server.utils.CoordinateUtil;
import com.zxy.ziems.server.utils.tree.TreeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备抽象
 *
 * @author chdzq
 * @create 2023/3/22
 */
@Service
public class DeviceServiceImpl extends ServiceImplX<DeviceMapper, DeviceEntity> implements DeviceService {

    @Autowired
    private ChannelService channelService;

    @Autowired
    private ChannelDeviceService channelDeviceService;

    @Autowired
    private DlPointService dlPointService;
    @Autowired
    private DevicePropertyService devicePropertyService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DeviceDTO dto) {
        doCheckBeforeSaveAction(dto);
        DeviceEntity entity = DeviceConvertor.INSTANCE.deviceDTOConvert2DO(dto);

        Coordinate coordinate = CoordinateUtil.calculteCoordinate(dto.getCoordinate(), sceneService.getById(dto.getSceneId()));
        entity.setAbsoluteX(coordinate.getX());
        entity.setAbsoluteY(coordinate.getY());
        entity.setAbsoluteZ(coordinate.getZ());
        doGetProcessHandlerBy(dto.getType())
                .ifPresent(($0) -> $0.doAddDevice(dto, entity));
        save(entity);
    }

    @Override
    public String saveEntity(DeviceEntity deviceEntity) {

        DeviceEntity deviceEntity1 = getByCode(deviceEntity.getCode());
        if (deviceEntity1 != null) {
            return deviceEntity1.getId();
        } else {
            this.save(deviceEntity);
            return deviceEntity.getId();
        }
    }

    /**
     * 获取处理额外信息
     *
     * @param deviceType
     */
    private Optional<DeviceExtraProcessor> doGetProcessHandlerBy(String deviceType) {
        if (CollectionUtil.isEmpty(extraProcessors)) {
            return Optional.empty();
        }
        Optional<DeviceExtraProcessor> first = extraProcessors.stream().filter(($0) -> $0.supportBy(deviceType)).findFirst();
        return first;
    }

    private void doCheckBeforeSaveAction(DeviceDTO dto) {
        if (StrUtil.isNotBlank(dto.getId())) {
            DeviceEntity entity = getById(dto.getId());
            AssertUtil.nonNull(entity, "设备不存在");
            if (StrUtil.isNotBlank(dto.getType())) {
                AssertUtil.isTrue(dto.getType().equals(entity.getTypeCode()), "设备类型不一致");
            } else {
                dto.setType(entity.getTypeCode());
            }
        }

        if (StrUtil.isNotBlank(dto.getCode())) {
            DeviceEntity old = getByCode(dto.getCode());
            if (null != old && !Objects.equals(old.getId(), dto.getId())) {
                throw BusinessExceptionUtil.exception("设备编码重复");
            }
        }

        if (StrUtil.isNotBlank(dto.getSceneId())) {
            SceneEntity scene = sceneService.getById(dto.getSceneId());
            AssertUtil.nonNull(scene, "关联的场景不存在");
            AssertUtil.isTrue(SceneType.FLOOR.getCode().equals(scene.getType()), "关联的场景不是楼层");
        }


        if (StrUtil.isNotBlank(dto.getType())) {
            DeviceTypeEntity deviceType = typeService.getByCode(dto.getType());
            AssertUtil.nonNull(deviceType, "设备类型不存在");
        }

        if (StrUtil.isNotBlank(dto.getOrgId())) {
            Org org = orgService.getById(dto.getOrgId());
            AssertUtil.nonNull(org, "部门不存在");

        }
    }


    /**
     * 检测设备是否可以删除
     *
     * @param id
     */
    private void doCheckBeforeDeleteAction(String id) {
        AssertUtil.isFalse(classifyDevicePropertyService.countByDeviceId(id) > 0, "设备存在分类");


        AssertUtil.isFalse(monitorGroupDeviceService.countByDeviceId(id) > 0, "设备存在监控分组");

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DeviceDTO dto) {
        doCheckBeforeSaveAction(dto);
        DeviceEntity entity = DeviceConvertor.INSTANCE.deviceDTOConvert2DO(dto);
        if (StrUtil.isNotBlank(dto.getSceneId())) {
            Coordinate coordinate = CoordinateUtil.calculteCoordinate(dto.getCoordinate(), sceneService.getById(dto.getSceneId()));
            entity.setAbsoluteX(coordinate.getX());
            entity.setAbsoluteY(coordinate.getY());
            entity.setAbsoluteZ(coordinate.getZ());
        }
        doGetProcessHandlerBy(dto.getType())
                .ifPresent(($0) -> $0.doUpdateDevice(dto, getById(dto.getId())));
        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String id) {
        DeviceEntity entity = getById(id);
        if (null == entity) {
            return;
        }

        // 校验是否可以删除
        doCheckBeforeDeleteAction(id);


        doGetProcessHandlerBy(entity.getTypeCode())
                .ifPresent(($0) -> $0.doRemoveDevice(entity.getCode()));

        // 删除相关信息
        doDeleteBeforeDeeteAction(id);

        removeById(id);
    }

    private void doDeleteBeforeDeeteAction(String deviceId) {
        // 删除告警规则
        devicePropertyAlarmService.removeByDeviceId(deviceId);
        // 删除告警记录
        alarmRecordService.removeByDeviceId(deviceId);
    }

    @Override
    public void updateBy(DeviceEntity entity) {
        updateById(entity);
    }

    @Override
    public DeviceEntity getById(String id) {
        return super.getById(id);
    }

    private DeviceEntity getByCode(String code) {
        return getOne(DeviceEntity::getCode, code);
    }

    @Override
    public DeviceEntity getByCode(String code, String type) {
        if (StrUtil.isBlank(code) || StrUtil.isBlank(type)) {
            return null;
        }
        LambdaQueryWrapperX<DeviceEntity> wrapper = WrapperX.<DeviceEntity>lambdaQuery()
                .eq(DeviceEntity::getCode, code)
                .eq(DeviceEntity::getTypeCode, type);
        return getOne(wrapper);
    }

    @Override
    public List<DeviceEntity> listByIdList(Collection<? extends Serializable> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return new ArrayList<>(0);
        }
        return super.listByIds(idList);
    }

    @Override
    public List<DeviceVO<Object>> listByCodeList(String type, String name) {
        LambdaQueryWrapperX<DeviceEntity> queryWrapperX = WrapperX.<DeviceEntity>lambdaQuery()
                .eqIfPresent(DeviceEntity::getTypeCode, type)
                .likeIfPresent(DeviceEntity::getName, name);
        List<DeviceEntity> list = list(queryWrapperX);
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<>(0);
        }
        return richByEntities(list);
    }

    @Override
    public DeviceVO<Object> viewById(String id) {
        DeviceEntity entity = getById(id);
        if (null == entity) {
            return null;
        }

        List<DeviceVO<Object>> devices = richByEntities(List.of(entity));
        DeviceVO<Object> deviceVO = devices.get(0);
        doGetProcessHandlerBy(entity.getTypeCode())
                .ifPresent(($0) -> deviceVO.setExtra($0.doGetExtra(entity.getCode())));
        return deviceVO;
    }

    @Override
    public PageResult<DeviceVO<Object>> pageListBy(DeviceQueryParam param) {
        PageResult<DeviceEntity> pageResult = customPage(param, (page, aParam) -> baseMapper.queryPageList(page, aParam));
        List<DeviceVO<Object>> list = richByEntities(pageResult.getList());
        return new PageResult<>(pageResult.getTotal(), list);
    }

    private List<DeviceVO<Object>> richByEntities(List<DeviceEntity> entities) {

        Map<String, SceneEntity> sceneMap = sceneService.list().stream().collect(Collectors.toMap(SceneEntity::getId, (a) -> a));

        Map<String, DeviceTypeEntity> typeMap = typeService.listAll().stream().collect(Collectors.toMap(DeviceTypeEntity::getCode, (a) -> a));

        Set<String> orgIdSet = entities.stream().map(DeviceEntity::getOrgId).collect(Collectors.toSet());
        List<Org> orgList = orgService.listByIds(orgIdSet);
        Map<String, Org> orgMap = orgList.stream().collect(Collectors.toMap(Org::getOrgId, (a) -> a));

        List<DeviceVO<Object>> list = entities.stream().map((entity) -> {
            DeviceTypeEntity type = StrUtil.isBlank(entity.getTypeCode()) ? null : typeMap.get(entity.getTypeCode());
            SceneEntity floor = StrUtil.isBlank(entity.getSceneId()) ? null : sceneMap.get(entity.getSceneId());
            SceneEntity building = Objects.isNull(floor) ? null : sceneMap.get(floor.getParentId());
            Org org = StrUtil.isBlank(entity.getOrgId()) ? null : orgMap.get(entity.getOrgId());
            return DeviceConvertor.INSTANCE.deviceDOConvert2VO(entity, type, building, floor, org);
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public List<DeviceTreeVO> tree() {
        List<DeviceTypeEntity> typeList = typeService.listAll();
        List<DeviceTreeVO> list = new ArrayList<>(
                typeList.stream().map((type) -> DeviceTreeVO.builder()
                                .id(type.getCode())
                                .name(type.getName())
                                .type(DeviceTreeVO.DEVICE_TYPE)
                                .build())
                        .toList()
        );

        List<DeviceEntity> deviceList = this.list();
        list.addAll(
                deviceList.stream()
                        .map((device) -> DeviceTreeVO.builder()
                                .id(device.getId())
                                .parentId(device.getTypeCode())
                                .name(device.getName())
                                .type(DeviceTreeVO.DEVICE)
                                .build()
                        ).toList()
        );

        return TreeUtils.tree(list);
    }

    @Override
    public List<DeviceAlarmVO> listAddressAndAlarm(String sentId, List<String> typeCodes) {

        List<DeviceEntity> deviceEntityList = baseMapper.queryAddressAndAlarm(typeCodes, sentId);

        Set<String> deviceIds =
                deviceEntityList.stream().map(m -> m.getId()).collect(Collectors.toSet());


        List<AlarmRecordDeviceVO> alarmRecordDeviceVOList = alarmRecordService.listByDeviceIds(deviceIds);
        Map<String, List<AlarmRecordDeviceVO>> alarmRecordMap = alarmRecordDeviceVOList.stream().collect(Collectors.groupingBy(m -> m.getDeviceId()));

        List<DeviceAlarmVO> deviceAlarmVOList = deviceEntityList.stream().map(entity -> {
            DeviceAlarmVO deviceAlarmVO = DeviceConvertor.INSTANCE.deviceDOConvert2AlarmVO(entity);
            List<AlarmRecordDeviceVO> alarmRecordDeviceVOList1 = alarmRecordMap.get(deviceAlarmVO.getId());
            deviceAlarmVO.setAlarmRecordDeviceVOList(alarmRecordDeviceVOList1);

            return deviceAlarmVO;
        }).collect(Collectors.toList());


        return deviceAlarmVOList;
    }

    @Override
    public void batchSaveOrUpdate(List<DeviceEntity> deviceList, String deviceType) {
        saveOrUpdateBatch(deviceList, DeviceEntity::getCode, wrapper -> {
            wrapper.eq(DeviceEntity::getTypeCode, deviceType);
        }, 1000);
    }

    @Override
    public void saveOrUpdateById(List<DeviceEntity> deviceList) {
        updateBatchById(deviceList);
    }


    @Override
    public List<SceneDeviceAlarmCountVO> countDeviceAlarm(List<String> deviceTypeCodes) {
        return baseMapper.countDeviceAlarm(deviceTypeCodes);
    }

    @Transactional
    @Override
    public DeviceEntity getByCodeAndAdd(String code, String type) {
        DeviceEntity deviceEntity = getByCode(code, type);
        if (Objects.isNull(deviceEntity)) {
            DeviceDTO dto = new DeviceDTO();
            dto.setCode(code);
            dto.setName(code);
            dto.setType(type);
            this.add(dto);
            deviceEntity = this.getByCode(code, type);
        }
        return deviceEntity;
    }

    @Override
    public void updateAlarmStatus(String deviceId, Integer alarmStatus) {
        DeviceEntity entity = new DeviceEntity();
        entity.setId(deviceId);
        entity.setAlarmStatus(alarmStatus);
        baseMapper.updateById(entity);
    }

    private AlarmRecordService alarmRecordService;


    @Autowired
    public void setAlarmRecordService(@Lazy AlarmRecordService alarmRecordService) {
        this.alarmRecordService = alarmRecordService;
    }


    private DeviceTypeService typeService;

    @Autowired
    public void setTypeService(DeviceTypeService deviceTypeService) {
        this.typeService = deviceTypeService;
    }

    private SceneService sceneService;

    @Autowired
    public void setSceneService(SceneService sceneService) {
        this.sceneService = sceneService;
    }

    private OrgService orgService;

    @Autowired
    public void setOrgService(OrgService orgService) {
        this.orgService = orgService;
    }

    private List<DeviceExtraProcessor> extraProcessors;

    @Autowired(required = false)
    @Qualifier
    public void setExtraProcessors(List<DeviceExtraProcessor> deviceExtraProcessors) {
        this.extraProcessors = deviceExtraProcessors;
    }

    private List<DeviceSynchronizeExecutor> synchronizeExecutors;

    @Autowired(required = false)
    @Qualifier
    public void setSynchronizeExecutors(List<DeviceSynchronizeExecutor> synchronizeExecutors) {
        this.synchronizeExecutors = synchronizeExecutors;
    }


    /**
     * 告警点位数
     *
     * @param param
     * @return
     */

    @Override
    public List<SceneTreeAlarmVO> getAlarmTreeBy(SceneTreeParam param) {
        List<SceneEntity> sceneList = sceneService.inheritListBy(param.getSceneId());

        // 过滤
        List<String> filterParentIds = sceneService.getFilterParentIds();
        List<SceneEntity> sceneFilterList = sceneList.stream().filter(m -> CollectionUtil.isEmpty(filterParentIds) ||
                !filterParentIds.contains(m.getParentId()) && !filterParentIds.contains(m.getId())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(sceneList)) {
            return new ArrayList<>(0);
        }


        List<SceneDeviceAlarmCountVO> sceneDeviceAlarmCountVOList = this.countDeviceAlarm(AlarmTypeParamEnum.GAS.getCode());

        Map<String, Integer> sceneAlarmCountMap = sceneFilterList.stream().map(m -> {
            SceneDeviceAlarmCountVO sceneDeviceAlarmCountVO = new SceneDeviceAlarmCountVO();
            Integer count = 0;
            if (m.getParentId().equals("0")) {
                List<String> ids = sceneFilterList.stream().filter(n -> n.getParentId().equals(m.getId())).map(n -> n.getId()).collect(Collectors.toList());
                count = sceneDeviceAlarmCountVOList.stream().filter(n -> n.getSceneId() != null && ids.contains(n.getSceneId())).mapToInt(SceneDeviceAlarmCountVO::getAlarmCount)
                        .sum();
            } else {
                count = sceneDeviceAlarmCountVOList.stream().filter(n -> n.getSceneId() != null && n.getSceneId().equals(m.getId())).mapToInt(SceneDeviceAlarmCountVO::getAlarmCount)
                        .sum();
            }
            sceneDeviceAlarmCountVO.setSceneId(m.getId());
            sceneDeviceAlarmCountVO.setAlarmCount(count);
            return sceneDeviceAlarmCountVO;
        }).collect(Collectors.toMap(m -> m.getSceneId(), m -> m.getAlarmCount()));


        List<String> fileIds = sceneFilterList.stream().map(SceneEntity::getFileId).collect(Collectors.toList());
        List<FileEntity> fileEntities = fileService.listByIds(fileIds);
        Map<String, FileEntity> fileEntityMap = fileEntities.stream().collect(Collectors.toMap(FileEntity::getId, (a) -> a));
        List<SceneTreeAlarmVO> treeList = sceneFilterList.stream().map((a) -> {
            SceneTreeAlarmVO sceneTreeAlarmVO = SceneConvertor.INSTANCE.sceneDOConvert2TreeAlarmVO(a, fileEntityMap.get(a.getFileId()));
            Integer count = sceneAlarmCountMap.get(a.getId());
            sceneTreeAlarmVO.setAlarmCount(count);
            sceneTreeAlarmVO.setAlarmStatus(count > 0 ? 1 : 0);

            return sceneTreeAlarmVO;
        }).collect(Collectors.toList());

        List<SceneTreeAlarmVO> tree = TreeUtils.tree(treeList);
        //过滤
        return tree;
    }


    @Override
    public List<DeviceEntity> listByTypeCode(String typeCode) {
        QueryWrapper<DeviceEntity> queryWrapper = new QueryWrapperX<>();
        queryWrapper.lambda().eq(DeviceEntity::getTypeCode, typeCode);

        return
                this.list(queryWrapper);

    }

    @Override
    public List<DeviceEntity> listByIdListAndDelete(Set<String> deviceIdSet) {
        if (CollectionUtil.isEmpty(deviceIdSet)) return new ArrayList<>();
        return baseMapper.listByIdListAndDelete(deviceIdSet);
    }

    @Override
    public List<DeviceEntity> listByCodeListAndDelete(Set<String> deviceCodeSet) {
        if (CollectionUtil.isEmpty(deviceCodeSet)) {
            return new ArrayList<>();
        }
        return baseMapper.selectListByCodeListAndDelete(deviceCodeSet);
    }

    @Transactional
    @Override
    public String addBase(DeviceBaseDTO<Object> dto) {
        DeviceDTO deviceDTO = new DeviceDTO();
        BeanUtils.copyProperties(dto, deviceDTO);

        doCheckBeforeSaveAction(deviceDTO);

        ChannelEntity channelEntity = channelService.getById(dto.getChannelId());
        AssertUtil.nonNull(channelEntity, "未找到通道");

        DeviceEntity entity = DeviceConvertor.INSTANCE.deviceDTOConvert2DO(deviceDTO);

        save(entity);

        ChannelDeviceEntity channelDeviceEntity = new ChannelDeviceEntity();
        channelDeviceEntity.setDeviceId(entity.getId());
        channelDeviceEntity.setChannelId(dto.getChannelId());
        channelDeviceService.addEntity(channelDeviceEntity);

        return entity.getId();
    }

    @Override
    public void initDlDevice() {
        // 查看电力未增加信息
        List<DlPointEntity> list = dlPointService.noCreateDeviceList();

        ChannelEntity dl = channelService.getByName("DL");
        AssertUtil.nonNull(dl, "通道未找到");

        for (DlPointEntity dlPointEntity : list) {
            DeviceBaseDTO<Object> dto = new DeviceBaseDTO<>();
            dto.setChannelId(dl.getId());
            dto.setCode(dlPointEntity.getPointDesc());
            dto.setName(dlPointEntity.getPointDesc());
            dto.setType("Ammeter");
            String deviceId = addBase(dto);


            DevicePropertyDTO<Object> deviceProperty = new DevicePropertyDTO<>();
            deviceProperty.setDeviceId(deviceId);
            deviceProperty.setUnitId("1770376622305116160");
            deviceProperty.setDataTypeId("1770381347331145728");
            devicePropertyService.addDataTypeAndUnit(deviceProperty);
        }

    }

    @Transactional
    @Override
    public void batchAddDevice(BatchAddDevicePropertyDTO batchAddDevicePropertyDTO) {
        for (String code : batchAddDevicePropertyDTO.getCodes()) {
            DeviceBaseDTO<Object> dto = new DeviceBaseDTO<>();
            dto.setChannelId(batchAddDevicePropertyDTO.getChannelId());
            dto.setCode(code);
            dto.setName(code);
            dto.setType(batchAddDevicePropertyDTO.getType());
            String deviceId = addBase(dto);

            DevicePropertyDTO<Object> deviceProperty = new DevicePropertyDTO<>();
            deviceProperty.setDeviceId(deviceId);
            deviceProperty.setUnitId(batchAddDevicePropertyDTO.getUnitId());
            deviceProperty.setDataTypeId(batchAddDevicePropertyDTO.getDataTypeId());
            devicePropertyService.addDataTypeAndUnit(deviceProperty);
        }
    }

    private FileService fileService;

    @Autowired
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }


    private ClassifyDevicePropertyService classifyDevicePropertyService;

    @Autowired
    public void setClassifyDevicePropertyService(ClassifyDevicePropertyService classifyDevicePropertyService) {
        this.classifyDevicePropertyService = classifyDevicePropertyService;
    }

    private MonitorGroupDeviceService monitorGroupDeviceService;

    @Autowired
    @Lazy
    public void setMonitorGroupDeviceService(MonitorGroupDeviceService monitorGroupDeviceService) {
        this.monitorGroupDeviceService = monitorGroupDeviceService;
    }

    private DevicePropertyAlarmService devicePropertyAlarmService;

    @Autowired
    @Lazy
    public void setDevicePropertyAlarmService(DevicePropertyAlarmService devicePropertyAlarmService) {
        this.devicePropertyAlarmService = devicePropertyAlarmService;
    }


}
